package com.kaf.common.filter;

import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;

import java.io.IOException;

/**
 * 请求日志过滤器
 * 记录请求和响应信息，便于调试和排查问题
 */
@Slf4j
@Component
@Order(1)
public class RequestLogFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        // 包装请求和响应以便多次读取内容
        ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(httpRequest);
        ContentCachingResponseWrapper wrappedResponse = new ContentCachingResponseWrapper(httpResponse);

        long startTime = System.currentTimeMillis();

        try {
            chain.doFilter(wrappedRequest, wrappedResponse);
        } finally {
            long duration = System.currentTimeMillis() - startTime;
            // 记录请求信息
            logRequest(wrappedRequest, duration);
            // 记录响应信息（可选）
            logResponse(wrappedResponse);
            // 将响应内容拷贝到真实响应中
            wrappedResponse.copyBodyToResponse();
        }
    }

    /**
     * 记录请求信息
     * @param request 请求
     * @param duration 处理时长
     */
    private void logRequest(ContentCachingRequestWrapper request, long duration) {
        String requestURI = request.getRequestURI();
        String method = request.getMethod();
        String queryString = request.getQueryString();
        String clientIP = getClientIP(request);

        log.info("请求: {} {}?{} | 客户端IP: {} | 耗时: {}ms",
                method, requestURI, queryString, clientIP, duration);
    }

    /**
     * 记录响应信息
     * @param response 响应
     */
    private void logResponse(ContentCachingResponseWrapper response) {
        int status = response.getStatus();
        log.debug("响应状态: {}", status);
    }

    /**
     * 获取客户端真实IP
     * @param request 请求
     * @return 客户端IP
     */
    private String getClientIP(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}
